package jfapps;

/**
 * Created : Mar 1, 2012
 *
 * @author pquiring
 */

import java.util.*;
import java.awt.*;
import javax.swing.*;

import javaforce.*;
import javaforce.linux.*;

public class MainPanel extends javax.swing.JPanel {

  /**
   * Creates new form AppsPanel
   */
  public MainPanel() {
    initComponents();
    This = this;
    loadSection();
    initLayout();
    Linux.detectDistro();
    switch (Linux.distro) {
      case Ubuntu: distroIdx = 2; break;
      case Fedora: distroIdx = 3; break;
      default: JFAWT.showError("Error", "unsupported distro"); System.exit(0);
    }
  }

  /**
   * This method is called from within the constructor to initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is always
   * regenerated by the Form Editor.
   */
  @SuppressWarnings("unchecked")
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {

    jScrollPane1 = new javax.swing.JScrollPane();
    sections = new javax.swing.JList();
    appsScroll = new javax.swing.JScrollPane();
    apps = new javax.swing.JPanel();
    searchField = new javax.swing.JTextField();
    search = new javax.swing.JButton();

    sections.setModel(new javax.swing.AbstractListModel() {
      String[] strings = { "Web", "Office", "Graphics", "MultiMedia", "Communcations", "System", "Development" };
      public int getSize() { return strings.length; }
      public Object getElementAt(int i) { return strings[i]; }
    });
    sections.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
    sections.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
      public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
        sectionsValueChanged(evt);
      }
    });
    jScrollPane1.setViewportView(sections);

    appsScroll.addComponentListener(new java.awt.event.ComponentAdapter() {
      public void componentResized(java.awt.event.ComponentEvent evt) {
        appsScrollComponentResized(evt);
      }
    });

    apps.setLayout(null);
    appsScroll.setViewportView(apps);

    searchField.addKeyListener(new java.awt.event.KeyAdapter() {
      public void keyTyped(java.awt.event.KeyEvent evt) {
        searchFieldKeyTyped(evt);
      }
    });

    search.setText("Search");
    search.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        searchActionPerformed(evt);
      }
    });

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
    this.setLayout(layout);
    layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addGroup(layout.createSequentialGroup()
            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 124, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(appsScroll, javax.swing.GroupLayout.DEFAULT_SIZE, 370, Short.MAX_VALUE))
          .addGroup(layout.createSequentialGroup()
            .addComponent(searchField)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(search)))
        .addContainerGap())
    );
    layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 481, Short.MAX_VALUE)
          .addComponent(appsScroll))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(searchField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(search))
        .addContainerGap())
    );
  }// </editor-fold>//GEN-END:initComponents

  private void sectionsValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_sectionsValueChanged
    searchString = null;
    section = sections.getSelectedIndex();
    loadSection();
  }//GEN-LAST:event_sectionsValueChanged

  private void searchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchActionPerformed
    search();
  }//GEN-LAST:event_searchActionPerformed

  private void searchFieldKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_searchFieldKeyTyped
    if (evt.getKeyChar() == java.awt.event.KeyEvent.VK_ENTER) search();
  }//GEN-LAST:event_searchFieldKeyTyped

  private void appsScrollComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_appsScrollComponentResized
    apps.doLayout();
  }//GEN-LAST:event_appsScrollComponentResized

  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JPanel apps;
  private javax.swing.JScrollPane appsScroll;
  private javax.swing.JScrollPane jScrollPane1;
  private javax.swing.JButton search;
  private javax.swing.JTextField searchField;
  private javax.swing.JList sections;
  // End of variables declaration//GEN-END:variables

  private int section = -1;
  private static MainPanel This;
  private String searchString;
  private int distroIdx = -1;
  //name, desc, ubuntu, fedora
  private String data[][][] = {
    //Web
    {
      {"Chromium", "Google Chromium Web Browser (no flash)", "chromium-browser", null},
      {"Chrome", "Google Chrome Web Browser (flash)", "google-chrome-stable", "google-chrome-stable"},
      {"Firefox", "Firefox Web Browser", "firefox", "firefox"},
      {"Flash", "Flash media plugin", "flashplugin-installer", "flash-plugin"},
      {"Torrent", "Torrent Client", "jtorrent", "jtorrent"},
//      {"Java Web Plugin", "Java Applet support", "icedtea-6-plugin", "icedtea-web"},  //no java 8 support???
    },
    //Office
    {
      {"LibreOffice", "Edit office documents", "libreoffice", "libreoffice"},
      {"Google PDF Reader", "View PDF documents (requires chrome)", "chrome-pdf", "chrome-pdf"},
      {"Evince PDF Reader", "View PDF documents", "evince", "evince"},
    },
    //Graphics
    {
      {"Paint", "Edit images", "jpaint", "jpaint"},
    },
    //MultiMedia
    {
      {"Media Player", "Play Media files", "jmedia", "jmedia"},
      {"Audio Editor", "Edit audio files", "jaudio", "jaudio"},
      {"Video Creator", "Create video files", "jvideo", "jvideo"},
      {"Music Composer", "Create music", "jmusic", "jmusic"},
      {"Record Desktop", "Records your desktop or window to a video file", "jrecorddesktop", "jrecorddesktop"},
      {"Record Camera", "Records your camera to a video file", "jrecordcamera", "jrecordcamera"},
      {"Audacity", "Edit audio files", "audacity", "audacity"},
    },
    //Communications
    {
      {"jPhoneLite", "VoIP/SIP Phone", "jphonelite", "jphonelite"},
      {"jPBXLite", "VoIP/SIP PBX", "jpbxlite", "jpbxlite"},
    },
    //System
    {
      {"Archive Manager", "Manipulate Archive files (zip, tar)", "jarchive", "jarchive"},
      {"Calculator", "Perform calculations", "jcalc", "jcalc"},
      {"FTP Manager", "Manage files thru FTP", "jftp", "jftp"},
      {"Help System", "Integrated help system", "jhelp", "jhelp"},
      {"nVidia Drivers", "Improved 3D Graphics support for nVidia hardware", "nvidia-current", null},
      {"nVidia Settings", "Configure nVidia hardware", "nvidia-settings", null},
      {"Partition Editor", "Modify partition tables", "jparted", "jparted"},
      {"QEMU Manager", "Virtual Machine Manager", "jqemu", "jqemu"},
      {"Remote Desktop Manager", "Make connections to RDP/VNC remote desktops", "jremote", "jremote"},
      {"Repository Selector", "Select your repo geo-graphically", "jrepo", null},
      {"Terminal Emulator", "Access system shell (local or remote)", "jterm", "jterm"},
      {"Task Manager", "View running tasks and resources", "jtaskmgr", "jtaskmgr"},
      {"Text Editor", "Edit text files", "jtxtedit", "jtxtedit"},
      {"Wine", "Run MS-Windows apps", "wine", "wine"},
      {"DosBox", "Run MS-DOS apps", "dosbox", "dosbox"},
      {"Darling", "Run Mac OSX apps", "darling-amd64", null},
    },
    //Development
    {
      {"Java JDK 8", "Java Development Kit", "openjdk-8-jdk", null},
      {"NetBeans", "Extensible Java IDE", "netbeans", "netbeans-platform"},
      {"ant", "Build Java projects", "ant", "ant"},
      {"VisualVM", "Java Developement Tool", "jvisualvm", "jvisualvm"},
      {"hex", "hex editor", "jhex", "jhex"},
      {"hexbig", "hexbig editor (for very large files)", "jhexbig", "jhexbig"},
    },
  };

  private Dimension appsSize;

  private class AppsLayout implements LayoutManager {
//    private Vector<Component> list = new Vector<Component>();
    public void addLayoutComponent(String string, Component cmp) {
//      list.add(cmp);
    }

    public void removeLayoutComponent(Component cmp) {
//      list.remove(cmp);
    }

    public Dimension preferredLayoutSize(Container c) {
      if (appsSize == null) layoutContainer(c);
      return appsSize;
    }

    public Dimension minimumLayoutSize(Container c) {
      return preferredLayoutSize(c);
    }

    public void layoutContainer(Container c) {
      int cnt = c.getComponentCount();
      int x = appsScroll.getViewport().getWidth();
      if (x < 145) x = 145;  //min size
      int cx = 0;
      int cy = 0;
      for(int a=0;a<cnt;a++) {
        Component child = c.getComponent(a);
        child.setBounds(0, cy, x, 102);
        cy += 102;
      }
      c.setPreferredSize(new Dimension(x, cy));
      appsSize = new Dimension(x, cy);
    }
  }

  private void initLayout() {
    //again, can't figure out NetBeans layout mgrs
    apps.setLayout(new AppsLayout());
  }

  private void loadSection() {
    apps.removeAll();
    if (searchString != null) {
      doSearch();
      return;
    }
    if (section == -1) {
      JLabel label = new JLabel("Select a category on the left");
      label.setHorizontalAlignment(SwingConstants.CENTER);
      apps.add(label);
      update();
      return;
    }
    String sec[][] = data[section];
    for (int a = 0; a < sec.length; a++) {
      if (sec[a][distroIdx] == null) continue;
      String pkg = sec[a][distroIdx];
      if (pkg.startsWith("#web#")) {
        String web = pkg.substring(5);
        pkg = null;
        if (web.equals("pdf")) {
          pkg = null;  //not a package
        } else if (web.equals("chrome")) {
          pkg = "chrome";
        }
        if (pkg == null) pkg = "unknown";
      }
      App app = new App();
               //name      desc       pkg        installed
      app.setup(sec[a][0], sec[a][1], sec[a][distroIdx], Linux.isInstalled(sec[a][distroIdx]));
      apps.add(app);
    }
    update();
  }

  public static void reload() {
    Linux.updateInstalled();
    This.loadSection();
  }

  private void search() {
    searchString = searchField.getText();
    loadSection();
  }

  private void doSearch() {
    if (searchString.length() < 3) {
      JLabel label = new JLabel("Search field must be at least 3 chars");
      label.setHorizontalAlignment(SwingConstants.CENTER);
      apps.add(label);
      update();
      return;
    }
    String pkgs[][] = Linux.searchPackages(searchString);  //name, desc
    int cnt = 0;
    for(int a=0;a<pkgs.length;a++) {
      if (pkgs[a][0] == null) continue;
      App app = new App();
                //name       desc        pkg         installed
      app.setup(pkgs[a][0], pkgs[a][1], pkgs[a][0], Linux.isInstalled(pkgs[a][0]));
      apps.add(app);
      cnt++;
    }
    if (cnt == 0) {
      JLabel label = new JLabel("Search returned no results");
      label.setHorizontalAlignment(SwingConstants.CENTER);
      apps.add(label);
    }
    update();
  }

  private void update() {
    apps.doLayout();
    appsScroll.doLayout();
    apps.revalidate();
    apps.repaint();
  }
}
